#include "Containers/ListedObject.h"
#include "catch.hpp"

class Derived : public ListedObject<Derived>
{};

TEST_CASE("Testing ListedObject", "[single-file]")
{
  ListedObject<Double_t>           object1;
  ListedObject<std::vector<Int_t>> object2;
  ListedObject<std::vector<Int_t>> object3;
  Derived                          object4;
  Derived                          object5;
  Derived                          object6;

  SECTION("Testing GetNInstances")
  {
    REQUIRE(0 == ListedObject<std::string>::GetNInstances());
    REQUIRE(1 == ListedObject<Double_t>::GetNInstances());
    REQUIRE(2 == ListedObject<std::vector<Int_t>>::GetNInstances());
    REQUIRE(3 == Derived::GetNInstances());
  }

  SECTION("Testing ~ListedObject (destruct)")
  {
    auto object = new Derived;
    REQUIRE(4 == Derived::GetNInstances());
    delete object;
    REQUIRE(3 == Derived::GetNInstances());
  }

  SECTION("Testing iterator")
  {
    REQUIRE(Derived::IterIsEnd() == true);

    Derived::IterReset();

    REQUIRE(Derived::IterIsEnd() == false);
    REQUIRE(Derived::IterGetObject() != nullptr);

    Derived::IterNext();
    REQUIRE(Derived::IterGetObject() != nullptr);

    Derived::IterNext();
    REQUIRE(Derived::IterGetObject() != nullptr);

    Derived::IterNext();
    REQUIRE(Derived::IterGetObject() == nullptr);

    Derived::IterReset();
    REQUIRE(Derived::IterGetObject() != nullptr);
  }
}